package com.weilele.mvvm.base.helper

import android.util.SparseArray
import androidx.core.util.forEach
import androidx.lifecycle.MutableLiveData
import com.weilele.mvvm.adapter.IMvvmAdapter
import com.weilele.mvvm.adapter.MvvmListAdapter
import com.weilele.mvvm.adapter.MvvmRcvAdapter
import com.weilele.mvvm.adapter.refreshList
import com.weilele.mvvm.base.livedata.StatusData
import com.weilele.mvvm.base.livedata.createStatusLiveData
import com.weilele.mvvm.base.livedata.createStatusMediatorLiveData
import com.weilele.mvvm.base.livedata.data


/**
 * 分页帮助类，有需求再慢慢完善
 */
/**
 * 创建观察对象
 */
fun <T, P, H : PageHelper<T, P>> createPageHelperData() = createStatusLiveData<H>()


/**
 * 创建可监听的观察者
 */
fun <T, P, H : PageHelper<T, P>> createPageHelperMediatorData() = createStatusMediatorLiveData<H>()

/**
 * 创建默认的，类型为pageHelper
 */
fun <T> pageHelperData() = createPageHelperData<T, Any, PageHelper<T, Any>>()


/**
 * 创建可监听的观察者
 */
fun <T> pageHelperMediatorData() = createPageHelperMediatorData<T, Any, PageHelper<T, Any>>()

/**
 * 更新数据
 */
inline fun <T, P, reified H : PageHelper<T, P>> MutableLiveData<StatusData<H>>.updatePageHelper(
    pageIndex: Int,/*当前是第几页*/
    datas: MutableList<T>?,/*当前的页面的集合*/
    isFirstPage: Boolean,/*是否是第一页*/
    hasNextPage: Boolean,/*是否有下一页（即是否是最后一页）*/
    pageData: P? = null,/*当前页面的数据*/
    helper: H? = null,
): H {
    val pageHelper = helper ?: this.data ?: H::class.java.newInstance()
    pageHelper.updatePageValue(
        pageIndex,
        datas,
        isFirstPage,
        hasNextPage,
        pageData
    )
    return pageHelper
}

/**
 * 清除所有数据
 */
inline fun <T, P, reified H : PageHelper<T, P>> MutableLiveData<StatusData<H>>.clearPageHelper(
    helper: H? = null
): H {
    val pageHelper = helper ?: this.data ?: H::class.java.newInstance()
    pageHelper.clearPageValue()
    return pageHelper
}

/**
 * 刷新所有数据
 */
fun <T, Helper : PageHelper<T, *>> MvvmRcvAdapter<T>.refreshPageHelper(helper: Helper?) {
    val newList = mutableListOf<T>()
    helper?.eachPageList { _, value ->
        value?.let {
            newList.addAll(it)
        }
    }
    refreshList(newList)
}

/**
 * 刷新所有数据
 */
fun <T, Helper : PageHelper<T, *>> MvvmListAdapter<T>.refreshPageHelper(helper: Helper?) {
    val newList = mutableListOf<T>()
    helper?.eachPageList { _, value ->
        value?.let {
            newList.addAll(it)
        }
    }
    refreshList(newList)
}

open class PageHelper<T, P/*额外的存储对象*/> {
    //记录每一页的数据集合，总是按照key的大小排序，key为当前页数
    private val _datasMap = SparseArray<MutableList<T>?>()

    //记录每一页的数据,总是按照key的大小排序，key为当前页数
    private val _pageMap = SparseArray<P?>()
    private var _isFirstPage = true
    private var _hasNextPage = true
    private var _pageIndex = 0

    /**
     * 是否是第一页
     */
    val isFirstPage: Boolean
        get() = _isFirstPage

    /**
     * 当前页面
     */
    val currentPageIndex: Int
        get() = _pageIndex


    /**
     * 是否还有下一页
     */
    val hasNextPage: Boolean
        get() = _hasNextPage

    /**
     * 是否还有上一页
     * 如果不是第一页，就还有上一页
     */
    val hasPrePage: Boolean
        get() = !isFirstPage

    /**
     * 当前页面数据
     */
    val currentPageData: P?
        get() = getPageData(currentPageIndex)

    /**
     * 当前页面集合
     */
    val currentPageList: MutableList<T>?
        get() = getPageList(currentPageIndex)

    /**
     * 暴露变量
     */
    val pageDataMap
        get() = _pageMap

    /**
     * 暴露变量
     */
    val pageListMap
        get() = _datasMap

    /**
     * 循环数据
     */
    fun eachPageData(action: (key: Int, value: P?) -> Unit) {
        _pageMap.forEach(action)
    }


    /**
     * 获取当前页面数据
     */
    fun getPageData(index: Int) = _pageMap[index]

    /**
     * 移除某个页面数据
     */
    fun removePageData(index: Int?) {
        if (index == null) {
            _pageMap.clear()
        } else {
            _pageMap.remove(index)
        }
    }

    /**
     * 移除某个页面集合
     */
    fun removePageList(index: Int?) {
        if (index == null) {
            _datasMap.clear()
        } else {
            _datasMap.remove(index)
        }
    }

    /**
     * 获取当前页面集合
     */
    fun getPageList(index: Int) = _datasMap[index]

    /**
     * 循环数据
     */
    fun eachPageList(action: (key: Int, value: MutableList<T>?) -> Unit) {
        _datasMap.forEach(action)
    }

    /**
     * 移除某个页面数据
     */
    fun removePage(pageIndex: Int?) {
        if (pageIndex == null) {
            _datasMap.clear()
            _pageMap.clear()
        } else {
            _datasMap.remove(pageIndex)
            _pageMap.remove(pageIndex)
        }
    }

    /**
     * hasNextPage 和 pageTotal 二选一，两个都有，则以hasNextPage为准
     * isClearOld：是否清除旧数据，针对那种页面展示固定数据，页数可以随意变更（不是按照顺序分页加载的情况）
     */
    fun updatePageValue(
        pageIndex: Int,/*当前是第几页*/
        datas: MutableList<T>?,/*当前的页面的集合*/
        isFirstPage: Boolean,/*是否是第一页*/
        hasNextPage: Boolean,/*是否有下一页（即是否是最后一页）*/
        pageData: P? = null,/*当前页面的数据*/
    ) {
        //当前索引
        _pageIndex = pageIndex
        //是否第一页
        _isFirstPage = isFirstPage
        //是否有下一页
        _hasNextPage = hasNextPage
        //对集合赋值
        _datasMap.put(pageIndex, datas)
        pageData?.let {
            _pageMap.put(pageIndex, it)
        }
    }

    /**
     * 清除所有数据
     */
    fun clearPageValue() {
        _pageIndex = 0
        _isFirstPage = true
        _datasMap.clear()
        _pageMap.clear()
        _hasNextPage = true
    }

    /**
     * 设置滚动到底部监听
     */
    fun setOnListScrollEndListener(adapter: IMvvmAdapter<T>, call: Function0<Unit>?) {
        if (call == null) {
            adapter.setOnScrollEndListener(null)
            return
        }
        adapter.setOnScrollEndListener {
            if (hasNextPage) {
                call.invoke()
            }
        }
    }
}